import {
  Form,
  Input,
  DatePicker,
  Select,
  Row,
  Col,
  InputNumber,
  Upload,
  message,
  Radio,
  TreeSelect,
  Button,
  AutoComplete,
  Image,
  Cascader,
  ConfigProvider,
  Tooltip,
  Modal
} from 'antd';
import moment from 'moment';
import React, { useEffect, memo, useState } from 'react';
import { LoadingOutlined, UploadOutlined, RetweetOutlined } from '@ant-design/icons';
import UploadCom from '../UploadCom';
import mockfile from './mockfile.js';
import zhCN from 'antd/lib/locale/zh_CN';

moment.locale('zh-cn');

const { TreeNode } = TreeSelect;
const { RangePicker } = DatePicker;
let { Option } = Select;

let loop = (data, title, key, children) =>
  data &&
  data?.length > 0 &&
  data?.map((item) => {
    let defaulttitle = title ? title : 'title',
      defaultkey = key ? key : 'key',
      defaultchildren = children ? children : 'children';
    const titles = <span>{item[defaulttitle]}</span>;
    if (item[defaultchildren]) {
      return (
        <TreeNode value={item[defaultkey]} key={item[defaultkey]} title={titles}>
          {loop(item[defaultchildren])}
        </TreeNode>
      );
    } else {
      return <TreeNode value={item[defaultkey]} key={item[defaultkey]} title={titles} />;
    }
  });

function filter(inputValue, path) {
  return path.some((option) => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
}

function formartData(item, val) {
  let formartValue = val;
  if (item.type == 'upload') {
    let stepval = val ? (Array.isArray(val) ? val : val.fileList) : [];
    formartValue = stepval.map((it) => {
      if (it.response) {
        return it?.response?.data?.dataList ? it?.response?.data?.dataList[0] : [];
      } else {
        return it ? it : null;
      }
    });
    // if (item.limit == 1) {
    //   formartValue = formartValue[0] ? formartValue[0] : '';
    // }
  } else if (item.type == 'datepicker') {
    formartValue = val ? val.format(item.format ? item.format : 'YYYY-MM-DD') : null;
  } else if (item.type == 'daterange') {
    formartValue =
      val && Array.isArray(val)
        ? val.map((it) => (it ? moment(it).format(item.format ? item.format : 'YYYY-MM-DD') : null))
        : [];
  }
  return formartValue;
}

let InitForm = ({
  fields,
  onChange,
  submitting,
  submitData,
  actions,
  col,
  mode,
  formRef,
  style,
  reset,
  row,
  rowCol,
  autoSubmit,
  layout,
  children,
  vs,
  title,
  setvs
}) => {
  console.log(vs);
  let [Dom, cDom] = useState([]),
    [cururl, setcururl] = useState(''),
    [loading, sload] = useState(false),
    [form] = Form.useForm(),
    [filelist, cfilelist] = useState({}),
    [link, clink] = useState({}),
    [belink, cbelink] = useState({}),
    [visible, setVisible] = useState(false),
    [optiondom, cdom] = useState({}),
    [len, clen] = useState(0),
    [ind, cind] = useState(0);

  form = formRef ? formRef : form;

  useEffect(() => {
    let Doms = [],
      klink = {},
      belinked = {},
      defaultfiles = {},
      allenin = 0;

    for (let i in fields) {
      let record = { ...fields[i] };
      if (record.defaultValueIndex || record.defaultValueIndex === 0) {
        allenin++;
      }
      //获取linked key
      if (record.linked === true) {
        klink[i] = record.value;
      }
      //获取belinked key
      if (record.belinked) {
        belinked[i] = record.belinked;
      }
      //初始化filelist
      if (record.type === 'upload') {
        let curfileList = record.value
          ? mockfile(Array.isArray(record.value) ? record.value : [record.value])
          : [];
        //default value

        defaultfiles[i] = curfileList ? (curfileList.fileList ? curfileList.fileList : []) : [];
        //formart value
        record.value = curfileList;
      } else if (record.type === 'datepicker') {
        record.value = record.value ? moment(record.value) : undefined;
      } else if (record.type === 'daterange') {
        record.value =
          record.value && Array.isArray(record.value)
            ? record.value.map((it) => it && moment(it))
            : [];
      }

      Doms.push(record);
    }
    clink(klink);
    cbelink(belinked);
    cfilelist(defaultfiles);
    cDom(Doms);
    clen(allenin);
  }, [fields]);

  useEffect(() => {
    //联动数据
    for (let i in fields) {
      let extraprops = getSelectLinked(fields[i]);
      let { options } = extraprops;
      getOptions(options, fields[i]);
    }
  }, [link]);

  const getCol = (itemcol) => {
    if (itemcol) {
      return itemcol;
    } else {
      return col ? col : { xs: 24, sm: 24, md: 12, lg: 12, xl: 12, xxl: 12 };
    }
  };

  //下拉框联动声明
  const getSelectLinked = (item) => {
    let names = item.belinked && Object.keys(item.belinked),
      hides = item.hides,
      options = item.options;
    if (names && names.length > 0) {
      if (item.belinked.hides && item.belinked.hides.length > 0) {
        let requiredlist = item.belinked.hides
          .filter((it) => {
            return it.required;
          })
          .map((it) => {
            if (it.equalvalue) {
              let equalvalue =
                it.equalvalue && Array.isArray(it.equalvalue) && it.equalvalue.length > 0
                  ? it.equalvalue.indexOf(link[it.name]) != -1
                  : link[it.name] == it.equalvalue;
              return equalvalue;
            } else if (it.unequalvalue) {
              let unequalvalue =
                it.unequalvalue && Array.isArray(it.unequalvalue) && it.unequalvalue.length > 0
                  ? it.unequalvalue.indexOf(link[it.name]) == -1
                  : link[it.name] != it.unequalvalue;
              return unequalvalue;
            } else {
              return true;
            }
          });

        let unrequiredlist = item.belinked.hides
          .filter((it) => {
            return !it.required;
          })
          .map((it) => {
            if (it.equalvalue) {
              let equalvalue =
                it.equalvalue && Array.isArray(it.equalvalue) && it.equalvalue.length > 0
                  ? it.equalvalue.indexOf(link[it.name]) != -1
                  : link[it.name] == it.equalvalue;
              return equalvalue;
            } else if (it.unequalvalue) {
              let unequalvalue =
                it.unequalvalue && Array.isArray(it.unequalvalue) && it.unequalvalue.length > 0
                  ? it.unequalvalue.indexOf(link[it.name]) == -1
                  : link[it.name] != it.unequalvalue;
              return unequalvalue;
            } else {
              return true;
            }
          });
        let rq = requiredlist.some((it) => it == true);
        let unrq = unrequiredlist.some((it) => it == true);
        hides = hides ? hides : rq || unrq;
      }
      if (!Array.isArray(item.belinked.options) && item.belinked.options) {
        let { database, params } = item.belinked.options,
          newparams = {};
        //获取传参联动的值
        for (let i in params) {
          if (params[i] == 'linked') {
            newparams[i] = form.getFieldValue(i);
          } else {
            newparams[i] = params[i];
          }
        }
        if (Array.isArray(database)) {
          options = database;
        } else {
          options = {
            database,
            params: newparams,
          };
        }
      }
    }
    return {
      hides,
      options,
    };
  };

  //格式化数据提交
  function formartSubmit(values) {
    let newvalue = { ...values };
    for (let i in fields) {
      newvalue[i] = formartData(fields[i], values[i]);
    }
    submitData(newvalue, () => {
      form.resetFields();
    });
  }

  useEffect(() => {
    if (autoSubmit && len == ind) {
      setTimeout(() => {
        form
          .validateFields()
          .then((values) => {
            formartSubmit(values);
          })
          .catch((error) => { });
      }, 200);
    }
  }, [len, ind]);

  const submitBtn = (
    <Button
      style={{ width: '100%', marginTop: row ? 18 : 0 }}
      htmlType="submit"
      type="primary"
      size={row ? 'middle' : 'large'}
      disabled={submitting || loading}
      onClick={() => {
        form
          .validateFields()
          .then((values) => {
            sload(true);
            formartSubmit(values);
            setTimeout(() => {
              sload(false);
            }, 1000);
          })
          .catch((error) => { });
      }}
    >
      {submitting || loading ? <LoadingOutlined /> : null}
      {submitting || loading ? '' : '提交'}
    </Button>
  );

  let getOptions = async (options, item) => {
    let curkey = item.name[0];
    if (Array.isArray(options)) {
      if (JSON.stringify(optiondom[curkey]) !== JSON.stringify(options)) {
        cdom((optiondom) => {
          return {
            ...optiondom,
            [curkey]: options,
          };
        });
      }
    } else if (options?.database) {
      let { database, params } = options ? options : {},
        dom = [];
      if (Array.isArray(database)) {
        dom = database;
      } else {
        let res = await database(params),
          dataList = [];
        if (res.code == 0) {
          if (item.type == 'treeselect') {
            dataList = res?.data;
          } else {
            dataList = res?.data?.dataList
              ? res?.data?.dataList.map((it) => {
                let label = item.formart ? item.formart[1] : 'name',
                  value = item.formart ? item.formart[0] : 'id';
                return item.type == 'cascader'
                  ? it
                  : {
                    label: it[label],
                    value: it[value],
                  };
              })
              : [];
          }
        }

        dom = dataList;
      }
      if (JSON.stringify(optiondom[curkey]) !== JSON.stringify(dom)) {
        cdom((optiondom) => {
          return {
            ...optiondom,
            [curkey]: dom,
          };
        });
      }
    }
  };

  let Formdom = (<div style={{ ...style, marginTop: -24 }} className="novia">
    <ConfigProvider locale={zhCN}>
      <Image
        src={cururl}
        width={0}
        height={0}
        preview={{
          visible,
          onVisibleChange: (visibles) => {
            if (visible) {
              setVisible(false);
            }
          },
        }}
      />
      <Form
        form={form}
        name="initform"
        layout={layout ? layout : 'vertical'}
        fields={Dom}
        onFinish={(values) => {
          //formartSubmit(values);
        }}
        onValuesChange={(changedValues, values) => {
          let newvalue = {};
          let linkkey = Object.keys(changedValues)[0];
          //联动逻辑
          for (let i in link) {
            if (i == linkkey) {
              clink({
                ...link,
                [i]: changedValues[i], //state修改当前value
              });
              //重置
              if (fields[i].linked) {
                let keyarr = [];
                for (let index in belink) {
                  if (
                    belink[index].options &&
                    Object.keys(belink[index].options.params).indexOf(i) != -1
                  ) {
                    keyarr.push(index);
                  }
                }
                keyarr.map((it) => form.setFieldsValue({ [it]: fields[it].multiple ? [] : '' }));
              }
            }
          }
          let allValues = form.getFieldsValue();
          for (let i in fields) {
            newvalue[i] = formartData(fields[i], allValues[i]);
            if (linkkey == i) {
              changedValues[i] = formartData(fields[i], allValues[i]);
            }
          }
          onChange && onChange(changedValues, newvalue);
        }}
      >
        <Row gutter={24} style={{ position: 'relative' }}>
          <Input type="text" name="userName" style={{ position: 'fixed', top: -999 }} />
          <Input type="password" style={{ position: 'fixed', top: -999 }} />
          {Dom.map((item, i) => {
            let extraprops = getSelectLinked(item);
            if (item.type == 'input' || item.type == 'password') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[
                      {
                        required: item.required,
                        message: `请输入${item.title}`,
                      },
                      {
                        validator: item.checkConfirm ? item.checkConfirm : null,
                      },
                      item.name[0].indexOf('phone') != -1
                        ? {
                          pattern: /^\d{11}$/,
                          message: '手机号格式不正确',
                        }
                        : item.name[0].indexOf('mail') != -1
                          ? {
                            pattern:
                              /^[a-z0-9A-Z]+[- | a-z0-9A-Z . _]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-z]{2,}$/,
                            message: '邮箱格式不正确',
                          }
                          : {},
                    ]}
                  >
                    {item.type == 'password' ? (
                      <Input.Password
                        bordered={mode == 'simple' ? false : true}
                        className={mode == 'simple' ? 'simple' : ''}
                        placeholder={item.placeholder ? item.placeholder : item.title}
                        allowClear
                        type={item.type}
                        maxLength={500}
                        disabled={item.disabled}
                      />
                    ) : (
                      <Input
                        bordered={mode == 'simple' ? false : true}
                        className={mode == 'simple' ? 'simple' : ''}
                        placeholder={item.placeholder ? item.placeholder : item.title}
                        allowClear
                        type={item.type}
                        maxLength={500}
                        disabled={item.disabled}
                        addonAfter={
                          item.adresscharge ? (
                            <Tooltip title="获取经纬度">
                              <RetweetOutlined
                                onClick={() => {
                                  let address = form.getFieldValue('address');
                                  fetch(
                                    'https://restapi.amap.com/v3/geocode/geo?key=e62898247d6cd9d2242b4894c35b94f8&address=' +
                                    address,
                                  )
                                    .then((res) => res.json())
                                    .then((result) => {
                                      if (result.geocodes[0]) {
                                        let locations = result.geocodes[0].location,
                                          lng = locations.split(',')[0],
                                          lat = locations.split(',')[1];

                                        form.setFieldsValue({ lng, lat });
                                      } else {
                                        message.error('无法识别该地址，请手动输入经纬度');
                                      }
                                    });
                                }}
                              />
                            </Tooltip>
                          ) : null
                        }
                      />
                    )}
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'autoinput') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[
                      {
                        required: item.required,
                        message: `请输入${item.title}`,
                      },
                    ]}
                  >
                    <AutoComplete
                      allowClear
                      placeholder={item.placeholder ? item.placeholder : item.title}
                      disabled={item.disabled}
                      options={
                        optiondom[item.name[0]] &&
                        optiondom[item.name[0]].length > 0 &&
                        optiondom[item.name[0]]
                      }
                      bordered={mode == 'simple' ? false : true}
                      className={mode == 'simple' ? 'simple' : ''}
                      filterOption={(inputValue, option) => {
                        return option.value && option.value.toString().indexOf(inputValue) !== -1;
                      }}
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'textarea') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请输入${item.title}` }]}
                  >
                    <Input.TextArea
                      maxLength={5000}
                      rows={4}
                      allowClear
                      placeholder={item.placeholder ? item.placeholder : item.title}
                      disabled={item.disabled}
                      bordered={mode == 'simple' ? false : true}
                      className={mode == 'simple' ? 'simple' : ''}
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'select') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <Select
                      allowClear
                      placeholder={item.placeholder ? item.placeholder : item.title}
                      style={{ width: '100%' }}
                      showSearch
                      mode={item.multiple ? 'multiple' : ''}
                      filterOption={(input, option) =>
                        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                      }
                      disabled={item.disabled}
                      maxTagCount={item.maxTagCount || 100}
                      bordered={mode == 'simple' ? false : true}
                      className={mode == 'simple' ? 'simple' : ''}
                    >
                      {optiondom[item.name[0]] &&
                        optiondom[item.name[0]].length > 0 &&
                        optiondom[item.name[0]]
                          .filter((it) => !it.hides)
                          .map((it, n) => {
                            return (
                              <Option
                                disabled={it.disabled}
                                key={n}
                                value={it.dicKey ? it.dicKey : it.value}
                              >
                                {it.dicName ? it.dicName : it.label}
                              </Option>
                            );
                          })}
                    </Select>
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'cascader') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <Cascader
                      fieldNames={item.fieldNames}
                      options={optiondom[item.name[0]]}
                      placeholder={item.placeholder ? item.placeholder : item.title}
                      style={{ width: '100%' }}
                      showSearch={{ filter }}
                      bordered={mode == 'simple' ? false : true}
                      disabled={item.disabled}
                      className={mode == 'simple' ? 'simple' : ''}
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'radio') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <Radio.Group
                      disabled={item.disabled}
                      options={
                        optiondom[item.name[0]] &&
                        optiondom[item.name[0]].length > 0 &&
                        optiondom[item.name[0]]
                      }
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'datepicker') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <DatePicker
                      className={mode == 'simple' ? 'simple' : ''}
                      style={{ width: '100%' }}
                      disabledDate={item.disabledDate ? item.disabledDate : null}
                      disabledTime={item.disabledDateTime ? item.disabledDateTime : null}
                      showToday={true}
                      picker={item.picker}
                      showTime={item.showTime}
                      format={item.format}
                      disabled={item.disabled}
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'daterange') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <RangePicker
                      className={mode == 'simple' ? 'simple' : ''}
                      style={{ width: '100%' }}
                      disabledDate={item.disabledDate ? item.disabledDate : null}
                      disabledTime={item.disabledDateTime ? item.disabledDateTime : null}
                      format={item.format}
                      showToday={true}
                      picker={item.picker}
                      showTime={item.showTime}
                      disabled={item.disabled}
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'inputnumber') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请输入${item.title}` }]}
                  >
                    <InputNumber
                      bordered={mode == 'simple' ? false : true}
                      className={mode == 'simple' ? 'simple' : ''}
                      style={{ width: '100%' }}
                      disabled={item.disabled}
                      min={item.min ? item.min : 0}
                      max={item.max}
                      formatter={item.formatter}
                      parser={item.parser}
                    />
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'upload') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <UploadCom item={item} />
                  </Form.Item>
                  <div style={{ fontSize: 12, color: '#999', marginTop: 0, marginBottom: 36 }}>
                    {item.description || ''}
                  </div>
                </Col>
              ) : null;
            } else if (item.type == 'treeselect') {
              let { title, key, children } = item.formart || {};
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  <Form.Item
                    style={{}}
                    label={item.title}
                    name={item.name[0]}
                    rules={[{ required: item.required, message: `请选择${item.title}` }]}
                  >
                    <TreeSelect
                      style={{ width: '100%' }}
                      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                      disabled={item.disabled}
                      allowClear
                      showSearch={optiondom[item.name[0]] && optiondom[item.name[0]].length > 0}
                      multiple={item.multiple}
                      treeDefaultExpandAll
                      placeholder={item.placeholder ? item.placeholder : item.title}
                      filterTreeNode={(input, node) => {
                        return node.title.props.children.indexOf(input) != -1;
                      }}
                    >
                      {optiondom[item.name[0]] &&
                        optiondom[item.name[0]].length > 0 &&
                        loop(optiondom[item.name[0]], title, key, children)}
                    </TreeSelect>
                  </Form.Item>
                </Col>
              ) : null;
            } else if (item.type == 'render') {
              return !extraprops.hides ? (
                <Col key={i} {...getCol(item.col)}>
                  {item.render && item.render()}
                </Col>
              ) : null;
            }
          })}

          <Col
            span={row ? 2 : reset ? 12 : 0}
            {...rowCol}
            style={{ padding: '12px', marginTop: row ? 18 : 0 }}
          >
            <Button
              size={row ? 'middle' : 'large'}
              style={{ width: '100%' }}
              onClick={() => {
                form.resetFields();
                form
                  .validateFields()
                  .then((values) => {
                    sload(true);
                    formartSubmit(values);
                    setTimeout(() => {
                      sload(false);
                    }, 1000);
                  })
                  .catch((error) => { });
              }}
            >
              重置
            </Button>
          </Col>
          <Col span={row ? 2 : reset ? 12 : 24} {...rowCol} style={{ padding: '12px' }}>
            {actions ? actions(form, submitBtn) : submitBtn}
          </Col>
          <Col span={24}>{children}</Col>
        </Row>
      </Form>
    </ConfigProvider>
  </div>)

   if(title){
    return <Modal
      visible={vs}
      title={title}
      destroyOnClose={true}
      footer={false}
      onCancel={()=>{
        setvs&&setvs(false)
      }}
      maskClosable={true}
    >
      {Formdom}
    </Modal>
   }else{
     return Formdom
   }           



};

export default memo(InitForm, (prev, next) => {
  if (prev.fields != next.fields || prev.vs !== next.vs) {
    return false;
  } else {
    return true;
  }
});
